﻿using NUnit.Framework;
using System.Web.Mvc;
using Moq;
using System.Collections.Specialized;
using System.Globalization;
using Inovout.Web.Binders;
using Moq.Protected;
using Inovout.Services;
using System;
using Inovout.Models;
using System.Collections.Generic;

namespace Inovout.Web.Tests.Binders
{
    [TestFixture]
    public class EntityModelBinderTestCase
    {
        public class Person : DataObject
        {
            public Person()
            {
            }
            public string Name { get; set; }
            public Address Address { get; set; }
            public int Age { get; set; }
            public List<Address> Addresses { get; set; }
               
        }
        public class Address
        {
            public string City { get; set; }
            public string PostCode { get; set; }
        }
        public class MvcApplication : WebApplication
        {
            public override void Run()
            {
                path = Environment.CurrentDirectory;
                applicationWrapper = new ApplicationWrapper(this);
                applicationWrapper.Initialize();
                ModelBinders.Binders.DefaultBinder = new EntityModelBinder();
            }
        }
        [Test]
        public void BindSimpleModel()
        {
            WebApplication applicaton = new MvcApplication();
            applicaton.Run();

            Mock<ControllerContext> mockControllerContext = new Mock<ControllerContext>();
            ControllerContext controllerContext = mockControllerContext.Object;

            ModelBindingContext bindingContext = new ModelBindingContext()
            {
                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(Person)),
                ValueProvider = new NameValueCollectionValueProvider(new NameValueCollection() { 
                {"Id","1"},{ "Name", "Ristona" },{"Address","{City:\"Nanjing\"}"},{"Addresses","[{City:\"NJ\"},{City:\"SH\"}]"} }, CultureInfo.CurrentCulture)
               // {"Id","1"},{ "Name", "Ristona" },{"Address.City","Nanjing"}  }, CultureInfo.CurrentCulture)
            };

            Mock<RepositoryService<Person>> mockPersonRepositoryService = new Mock<RepositoryService<Person>>();
            mockPersonRepositoryService.Setup(r => r.FindById(It.IsAny<object>()))
                .Returns(new Person { Name = "Huay", Address = new Address { City = "Shanghai",PostCode="210002" }, Age = 33 });

            ComponentRegistry.AddComponent<IRepositoryService<Person>>(mockPersonRepositoryService.Object);

            //Mock<EntityModelBinder> mockEntityModelBinder = new Mock<EntityModelBinder>();
            //mockEntityModelBinder.Protected().Setup<IRepositoryService>("GetRepositoryService", typeof(Type))
            //         .Returns(mockRepositoryService.Object);
            EntityModelBinder modelBinder = new EntityModelBinder();

            
            Person model = (Person)modelBinder.BindModel(controllerContext, bindingContext);
            Assert.AreEqual(model.Name, "Ristona");
            Assert.AreEqual(model.Address.City, "Nanjing");
            Assert.AreEqual(model.Age, 33);
            Assert.AreEqual(model.Addresses.Count, 2);
            Assert.AreEqual(model.Addresses[0].City, "NJ");

        }
    }
}
